package com.yonyou.crm.sprc.lead.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yonyou.crm.base.doc.service.BaseDocDetailBizServiceImpl;
import com.yonyou.crm.base.industry.service.IndustryBizServiceImpl;
import com.yonyou.crm.common.biz.service.BaseBizServiceImpl;
import com.yonyou.crm.common.enumeration.service.EnumBizServiceImpl;
import com.yonyou.crm.common.exception.CrmBusinessException;
import com.yonyou.crm.common.field.handler.FieldRelationHandler;
import com.yonyou.crm.common.field.relation.EnumFieldRelation;
import com.yonyou.crm.common.field.relation.FieldRelation;
import com.yonyou.crm.common.field.relation.RefFieldRelation;
import com.yonyou.crm.common.login.context.LoginContextConstant;
import com.yonyou.crm.common.page.entity.Page;
import com.yonyou.crm.common.search.entity.AppSearchPlanEnum;
import com.yonyou.crm.sact.schedule.entity.ScheduleObjectVO;
import com.yonyou.crm.sact.schedule.service.ScheduleObjectBizServiceImpl;
import com.yonyou.crm.sprc.lead.entity.LeadVO;
import com.yonyou.crm.sys.region.service.RegionsBizServiceImpl;
import com.yonyou.crm.sys.user.service.UserBizServiceImpl;
import com.yonyou.iuap.context.InvocationInfoProxy;

@Service
public class LeadBizServiceImpl extends BaseBizServiceImpl<LeadVO> {

	@Autowired
	private EnumBizServiceImpl enumService;
	
	@Autowired
    ScheduleObjectBizServiceImpl scheduleObjectService;
	
	@Autowired
	private IndustryBizServiceImpl industryBizService;
	
	@Autowired
	private RegionsBizServiceImpl regionService;
	
	@Autowired
	private BaseDocDetailBizServiceImpl baseDocDetailBizService;
	
	@Autowired
	private UserBizServiceImpl userService;
	
	/**
	 * 分页查询
	 * @param page
	 * @param paraMap
	 * @return
	 */
	public Page<LeadVO> getPage(Page<LeadVO> page, Map<String, Object> paramMap) {
		
		Page<LeadVO> rPage = null;
		if (paramMap == null) {
			paramMap = new HashMap<String, Object>();
		}
		
		paramMap.put("tenantId", InvocationInfoProxy.getTenantid());
		
		//全部、我负责、我参与、我关注、已逾期
		if ((paramMap.containsKey("option")) && (paramMap.get("option") != null)) {
			int option = (int)paramMap.get("option");
			String optionSql = "";
			if (option == AppSearchPlanEnum.OWNER.getValue()) {
				optionSql = " and owner_user_id = "+InvocationInfoProxy.getParameter(LoginContextConstant.UserId);
			} else if (option == AppSearchPlanEnum.REL.getValue()) {
				//TODO参与
				optionSql = "";
			} else if (option == AppSearchPlanEnum.FOLLOW.getValue()) {
				//TODO关注
				optionSql = "";
			} else if (option == AppSearchPlanEnum.CONVERSION.getValue()) {
				//TODO转化
				optionSql = " and state = 2";
			} else if (option == AppSearchPlanEnum.CLOSE.getValue()) {
				optionSql = " and state = 3";
			} else {
				//TODO全部
				optionSql = "";
			}
			paramMap.put("option", optionSql);
		}
		
		rPage = super.pageSelect(LeadVO.class, page, paramMap.keySet().toArray(new String[0]), paramMap.values().toArray(new Object[0]));
		
		if (rPage != null) {
			List<LeadVO> leadList = rPage.getData();
			if (leadList != null && leadList.size() > 0) {
				
				for (LeadVO vo : leadList) {
					vo.setOwnerUserInfo(userService.getDetail(vo.getOwnerUserId()));
				}
				
				trans(rPage.getData());
			}
		}

		return rPage;
		
	}

	@Override
	protected void beforeSaveVO(LeadVO vo) {
		super.beforeSaveVO(vo);

		if (isCompanyNameExist(vo)) {
			throw new CrmBusinessException("公司名称已存在");
		}
		
		Date date = new Date();
		Long userId = new Long(InvocationInfoProxy.getParameter("id"));
		
		vo.setCreatedTime(date);
		vo.setCreatedUserId(userId);
		vo.setModifiedTime(date);
		vo.setModifiedUserId(userId);
		
		vo.setFollowTime(date);
		
		if (vo.getOwnerUserId() == null || vo.getOwnerUserId().longValue() == 0) {
			vo.setOwnerUserId(userId);
		}

	}

	@Override
	protected void afterSaveVO(LeadVO vo) {
		super.afterSaveVO(vo);
	}

	@Override
	protected void beforeUpdateVO(LeadVO vo) {
		super.beforeUpdateVO(vo);
	}

	@Override
	protected void afterUpdateVO(LeadVO vo) {
		super.afterUpdateVO(vo);
	}

	/**
	 * 校验未处理线索的公司名称唯一性
	 * @param id
	 * @param name
	 * @return
	 */
	public boolean isCompanyNameExist(LeadVO vo) {
		Map<String, Object> paraMap = new HashMap<String, Object>();
		paraMap.put("id", vo.getId());
		paraMap.put("companyName", vo.getCompanyName());
		paraMap.put("tenantId", new Long(InvocationInfoProxy.getTenantid()));
		return dao.countAll(LeadVO.class, "getCountByCompanyName", paraMap) > 0;
	}
	
	private List<LeadVO> trans(List<LeadVO> voList) {
		
		if (voList != null && voList.size() > 0) {
			
			List<FieldRelation<LeadVO>> relations = new ArrayList<FieldRelation<LeadVO>>();
			relations.add(new EnumFieldRelation<LeadVO>(LeadVO.class, "gender", "genderName", enumService, "gender"));
			relations.add(new EnumFieldRelation<LeadVO>(LeadVO.class, "state", "stateName", enumService, "lead_state"));
			relations.add(new RefFieldRelation<LeadVO>(LeadVO.class, "level", new String[]{"levelName"}, baseDocDetailBizService, "selectFieldsByIds"));
			relations.add(new RefFieldRelation<LeadVO>(LeadVO.class, "source", new String[]{"sourceName"}, baseDocDetailBizService, "selectFieldsByIds"));
			relations.add(new RefFieldRelation<LeadVO>(LeadVO.class, "post", new String[]{"postName"}, baseDocDetailBizService, "selectFieldsByIds"));
			
			//行业
			relations.add(new RefFieldRelation<LeadVO>(LeadVO.class, "industryId", new String[]{"industryName"}, industryBizService, "selectFieldsByIds"));
			
			//省、市、区
			relations.add(new RefFieldRelation<LeadVO>(LeadVO.class, "province", new String[]{"provinceName"}, regionService, "selectFieldsByIds"));
			relations.add(new RefFieldRelation<LeadVO>(LeadVO.class, "city", new String[]{"cityName"}, regionService, "selectFieldsByIds"));
			relations.add(new RefFieldRelation<LeadVO>(LeadVO.class, "district", new String[]{"districtName"}, regionService, "selectFieldsByIds"));
			
			new FieldRelationHandler<LeadVO>().handler(voList, relations);
		
		}

		return voList;
	}
	
	public LeadVO getDetail(Long id) {
		
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("ownerId", new Long(InvocationInfoProxy.getParameter("id")));
		paramMap.put("id", id);
				
		LeadVO vo = (LeadVO) dao.selectOne(LeadVO.class, "getLeadById", paramMap);
		
		vo.setOwnerUserInfo(userService.getDetail(vo.getOwnerUserId()));
		
		if (vo != null) {
			trans(Arrays.asList(vo));
		}
		return vo;
	}
	
	public LeadVO save(LeadVO lead) {
		return super.saveVO(lead);
	}
	
	public LeadVO save(LeadVO lead, Map<String, Object> param) {
		
		lead = save(lead);
		@SuppressWarnings("unchecked")
		Map<String, String> relateMap = (Map<String, String>)param.get("relateMap");
		if ((relateMap != null) && (relateMap.size() > 0)) {
        	//TODO写入日程关联表
        	ScheduleObjectVO scheduleObject = new ScheduleObjectVO();
        	scheduleObject.setScheduleId(Long.valueOf(relateMap.get("id")));
        	Integer scheduleType = ScheduleObjectBizServiceImpl.getScheduleType(relateMap.get("type"));
        	scheduleObject.setScheduleType(scheduleType);
        	Long objType = ScheduleObjectBizServiceImpl.getObjType("lead");
        	scheduleObject.setObjType(objType);
        	scheduleObject.setObjId(lead.getId());
        	// 设置业务子类型
        	long subBnsType = ScheduleObjectBizServiceImpl.getBizObjType(String.valueOf(param.get("subBnsType")));
        	scheduleObject.setObjBiztype(subBnsType);
        	scheduleObjectService.save(scheduleObject);
        }
		return lead;
	}
	
	public String batchDelete(String[] ids) {
		Set<String> idSet = new HashSet<String>();
		for (String id : ids) {
			idSet.add(id);
		}
		
		int totalCount = idSet.size();
		
		StringBuffer reasonBuffer = new StringBuffer("【");
		
		//是否被业务对象引用，待实现
		List<Map<String, Object>> leadList = new ArrayList<Map<String,Object>>();
		
		if (leadList != null && leadList.size() > 0) {
			
			for (Map<String, Object> map : leadList) {
				
				reasonBuffer.append(map.get("name"));
				reasonBuffer.append(",");

				String typeId = map.get("id").toString();
				//被业务对象引用不能删除
				idSet.remove(typeId);
			}
			reasonBuffer.delete(reasonBuffer.length()-1, reasonBuffer.length());
			reasonBuffer.append("】当前线索已关联业务数据,不可删除！");
		}
		
		int successCount = idSet.size();
		int failCount = totalCount - idSet.size();
		String message = failCount == 0 ? "成功" + successCount + "条。" : "成功" + successCount + "条，失败" + failCount + "条。\n失败原因：" + reasonBuffer.toString();
		
		if (successCount > 0) {
			
			//删除线索
			super.batchDeleteByIDs(LeadVO.class, idSet.toArray(new String[0]));
		}
		
		return message;
	}
	
	/**
	 * 关注线索
	 * @param id
	 * @return
	 */
	public int saveFollow(Long id) {
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("leadId", id);
		param.put("userId", InvocationInfoProxy.getParameter("id"));
		int count = dao.countAll(LeadVO.class, "countFollow", param);
		if (count > 0) {
			return 1;
		}
		return dao.saveSql(LeadVO.class, "insertFollow", param);
	}
	
	/**
	 * 删除线索关注
	 * @param id
	 * @return
	 */
	public int deleteFollow(Long id) {
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("leadId", id);
		param.put("userId", InvocationInfoProxy.getParameter("id"));
		return dao.deleteSql(LeadVO.class, "deleteFollow", param);
	}
	
}
